# Configuration - Object from this class represents Entertainer's configuration
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import os
import ConfigParser
from ConfigParser import ParsingError

from backend.core.message_type_priority import MessageType, MessagePriority
from backend.core.message_handler import MessageHandler

class Configuration(MessageHandler):
    """
    Configuration of the Entertainer
    
    This class is an interface to all configuration parameters. All components
    of Entertainer should get configuration vales through this class. Object
    from this class reads current config files and returns values based on
    those files. If there are missing lines or other errors in config file,
    then object return default values defined in this class.
    """
    
    # Preferences file
    PREFERENCES_CONF = os.path.expanduser('~/.entertainer/preferences.conf')
    
    # Content file
    CONTENT_CONF = os.path.expanduser('~/.entertainer/content.conf')
    
    def __init__(self):
        """
        Read configuration files and setup this object.
        """
        self.content_config = ConfigParser.ConfigParser()
        self.preferences = ConfigParser.ConfigParser()
        try:
            self.content_config.readfp(open(self.__class__.CONTENT_CONF))
            self.preferences.readfp(open(self.__class__.PREFERENCES_CONF))
        except ParsingError:
            raise Exception("Syntax error in configuration file.")
        except IOError:
            raise IOError("Couldn't read config file.")
    
    def update_configuration(self):
        """
        Read configuration files again and update this object.
        """
        try:
            self.content_config.readfp(open(self.__class__.CONTENT_CONF))
            self.preferences.readfp(open(self.__class__.PREFERENCES_CONF))
        except ParsingError:
            raise Exception("Syntax error in configuration file.")
        except IOError:
            raise IOError("Couldn't read config file.")
    
    def get_theme_path(self):
        """
        Get absolute path of the used theme.
        @return: string (path)
        """
        theme_path = os.path.expanduser('~/.entertainer/themes')
        try:
            theme = self.preferences.get("General", "theme")
        except:
            return os.path.join(theme_path, "Default Light")

        if os.path.exists(os.path.join(theme_path, theme)):
            return os.path.join(theme_path, theme)
        else:
            return os.path.join(theme_path, "Default Light")
        
    def is_notifications_enabled(self):
        """
        Display on-screen notification bubbles on events.
        @return: boolean
        """
        try:
            result = self.preferences.getboolean("General", "display_notifications")
        except:
            return False
        return result
    
    def get_feed_fetch_interval(self):
        """
        Get time interval (in minutes) for feed fetching.
        @return: Integer
        """        
        try:
            result = self.content_config.getint("RSS", "fetch_interval")
        except:
            return 60 # Default is one hour
        return result
            
    def get_port(self):
        """
        Get backend server's port number.
        @return: Integer
        """
        try:
            result = self.preferences.getint("General", "backend_port")
        except:
            return 45054 # Default port
        return result
            
    def get_video_folders(self):
        """
        Get list of video folders
        @return:String Array
        """    
        #FIXME: We should prevent ~/.entertainer/cache/* to be in those folders
        #       This can lead to recursivnes: make thumbs of thumbs of thumbs...     
        try:
            folder_list = self.content_config.get("Videos", "folders")
            result = folder_list.split(';')
        except:
            return []
        return result

    def get_music_folders(self):
        """
        Get list of music folders
        @return: String Array
        """
        #FIXME: We should prevent ~/.entertainer/cache/* to be in those folders
        #       This can lead to recursivnes: make thumbs of thumbs of thumbs...   
        try:
            music_list = self.content_config.get("Music", "folders")
            result = music_list.split(';')
        except:
            return []
        return result
        
    def get_image_folders(self):
        """
        Get list of image folders
        @return: String Array
        """
        #FIXME: We should prevent ~/.entertainer/cache/* to be in those folders
        #       This can lead to recursivnes: make thumbs of thumbs of thumbs...          
        try:
            image_list = self.content_config.get("Images", "folders")
            result = image_list.split(';')
        except:
            return []
        return result
    
    def get_feeds(self):
        """
        Get list of feeds.
        @return: String Array
        """
        try:
            rss_feeds = self.content_config.get("RSS", "feeds")
            result = rss_feeds.split(';')
        except:
            return []
        return result
        
    def download_video_metadata(self):
        """Return True if video metadata should be downloaded, otherwise False"""
        try:
            result = self.content_config.getboolean("Videos", "download_metadata")
        except:
            return False
        return result
        
    def download_album_art(self):
        """
        Download album art from the Internet.
        @return: boolean
        """
        try:
            result = self.content_config.getboolean("Music", "download_album_art")
        except:
            return False
        return result
        
    def download_lyrics(self):
        """
        Download song lyrics from the Internet.
        @return: boolean
        """
        try:
            result = self.content_config.getboolean("Music", "download_lyrics")
        except:
            return False
        return result
    
    def show_effects(self):
        """
        Use animations on user interface.
        @return: boolean
        """
        try:
            result = self.preferences.getboolean("General", "show_effects")
        except:
            return False
        return result
    
    def transition_effect(self):
        """
        Which transition effect should be used when switching screens.
        @return: string (name of the effect)
        """
        try:
            result = self.preferences.get("General", "transition_effect")
        except:
            return False
        return result
        
    def start_in_fullscreen(self):
        """
        Return True if frontend should start in Fullscreen mode, otherwise False
        @return: boolean
        """
        try:
            result = self.preferences.getboolean("General", "start_in_fullscreen")
        except:
            return False
        return result
    
    def history_size(self):
        """
        Get screen history size. This determines how many screen are kept in
        memory when scrolling.
        @return: Integer
        """
        try:
            result = self.preferences.getint("General", "history_size")
        except:
            return 10
        return result
    
    # Implements MessageHandler interface
    def handleMessage(self, message):
        """
        Handle received messages.
        @param message: Received Message object
        """
        if message.get_type() == MessageType.CONTENT_CONF_UPDATED:
            self.updateConfiguration()
        elif message.get_type() == MessageType.PREFERENCES_CONF_UPDATED:
            self.updateConfiguration()
                    
    def getName(self):
        """
        Get name of the MessageHandler
        @return: string 
        """
        return "Configuration"
